﻿namespace VividKit.ComponentModel
{
    using System;
    using System.Threading.Tasks;
    using System.Windows;

    /// <summary>
    /// Provides a set of methods that implements the <see cref="T:IDispatcher"/> interface.
    /// </summary>
    internal class Dispatcher : IDispatcher
    {
        Task IDispatcher.InvokeAsync(Action action)
        {
            return InvokeAsyncImpl<object>(delegate
            {
                action();
                return null;
            });
        }

        Task<TResult> IDispatcher.InvokeAsync<TResult>(Func<TResult> callback)
        {
            return InvokeAsyncImpl(callback);
        }

        private static Task<TResult> InvokeAsyncImpl<TResult>(Func<TResult> callback)
        {
            var tcs = new TaskCompletionSource<TResult>();

            Deployment.Current.Dispatcher.BeginInvoke(delegate
            {
                try
                {
                    tcs.TrySetResult(callback());
                }
                catch (Exception x)
                {
                    tcs.TrySetException(x);
                }
            });

            return tcs.Task;
        }
    }
}